/*
定长对象池,使PageCach中不用在new Span 对象, 直接使用定长对象池分配
*/
#pragma once
#include "Common.h"

template <typename T>
class ObjectPoll {
public:
    ObjectPoll()
        : memory_(nullptr), rest_(0), freeList_()
    {}
    ~ObjectPoll()
    {}

    T* New() {
        int sz = sizeof(T); // 计算单个类型的大小
        T* objptr = nullptr;
        if (freeList_ != nullptr) {
            objptr = (T*)freeList_;
            freeList_ = *(void**)freeList_;
        }
        else {
            if (sz > rest_) {
                memory_ = (char*)SystemAlloc(8); // 16页大小内存
                rest_ = 8 * PAGE_SIZE;
                assert(memory_);
            }
              sz   =   sz >= sizeof(void*) ? sz : sizeof(void*);
            objptr =   (T*)memory_;
            memory_ += sz;
            rest_   -= sz;
        }
        // 定位new
        new (objptr) T(); // 调用构造
        return objptr;
    }

    void Delete(T* objptr) {
        objptr->~T(); // 调用析构
        *(void**)objptr = freeList_;
        freeList_ = objptr;
    }

private:
    char* memory_   = nullptr;  // 大内存块首地址
    size_t rest_    = 0;    // 大块内存剩余的字节数
    void* freeList_ = nullptr; // 释放的内存块链表
};
